<template>
  <div>
    <input-table v-model="$model.parameters" :show-header="false" v-if="$model.parameters?.length">

      <template #header>
        <div class="title">
          请求参数
        </div>
      </template>
      <el-table-column align="center" label="参数" width="150px">
        <template v-slot="scope">
          <label>{{ scope.row.key }}</label>
        </template>
      </el-table-column>

      <el-table-column align="center" label="值" width="180px">
        <template v-slot="scope">
          <el-input v-model="scope.row.value" placeholder="值"></el-input>
        </template>
      </el-table-column>

      <el-table-column align="center" label="脚本">
        <template v-slot="scope">
          <el-input v-model="scope.row.script" placeholder="脚本" type="textarea" autosize></el-input>
        </template>
      </el-table-column>
    </input-table>


    <template v-if="!!$model.apiDefine?.requestBodyParameters?.items?.length">
      <kv label="postBodyScript">
        <el-input v-model="$model.postBodyScript" type="textarea" autosize></el-input>
      </kv>
      <kv>
        <template #k>
          <div class="k">
            <div style="display: flex;flex-direction: column;align-items: flex-end;">
              postBody
              <el-button size="small" style="display: block" @click="model_change">切换</el-button>
            </div>
          </div>
        </template>
        <el-input v-if="$data.postBodyIsText" v-model="$model.postBody" type="textarea" autosize></el-input>
        <div v-else>

          <api-json-edit-value v-if="$model.apiDefine"
                               v-model="$model.apiDefine.requestBodyParameters"></api-json-edit-value>

        </div>
      </kv>
    </template>

    <slot></slot>
  </div>
</template>
<script setup>
import apiJsonEditValue from "../component/api-json-parameter-edit-value.vue";



defineOptions({
  name: "exe-api",
  inheritAttrs: true,
});

const $data = reactive({
  postBodyIsText: false
});

const $emit = defineEmits(["update:modelValue", "loaded"]);

//对象结构 ApiInstance ： { apiDefine , parameters , postJSON , ... }
var $model = defineModel({type: Object});


const getPostBody = function (defs) {
  var ret = {};
  defs.forEach(it => {
    var item = {};
    if (it.type == "Object") {
      item = getPostBody(it.items);
    } else if (it.type == "Number" || it.type == "Int" || it.type == "Float") {
      item = it.value || it.defaultValue || 0;
    } else {
      item = it.value || it.defaultValue || "";
    }
    if (it.isList) {
      item = [item];
    }
    ret[it.key] = item;
  })
  return ret;
};

const getDefineValue = json => {
  var ret = [];
  Object.keys(json).forEach(it => {
    var v = json[it];
    if (jv.isNull(v)) {
      return;
    }

    if (v.isObjectType()) {
      var sub = {};
      sub.key = it;
      sub.items = getDefineValue(v)
      ret.push(sub);
    } else {
      ret.push({key: it, value: v});
    }
  })
  return ret;
}


const api2ExecParameters = instance => {

  if (!instance.parameters) {
    instance.parameters = [];
  }
  var api = instance.apiDefine;

  //补url
  api.url.getVarKeys().distinct().forEach(p => {
    if (!api.requestUrlPathParameters.find(it => it.key == p)) {
      api.requestUrlPathParameters.push({key: it, type: "Text", stringType: "Normal"});
    }
    ;
  })

  var ps = [];
  ps.addAll(api.requestHeaderParameters);
  ps.addAll(api.requestUrlPathParameters);
  ps.addAll(api.requestUrlQueryParameters);

  //补
  ps.forEach(it => {
    if (instance.parameters.find(p => p.key == it.key)) {
      return;
    }
    instance.parameters.push({key: it.key, value: it.value || it.defaultValue || "", script: ""});
  });

  //构造 postBody
  if (api.requestBodyParameters.items.length) {
    instance.postBody = JSON.stringify(getPostBody(api.requestBodyParameters.items));
  }
  return instance;
}


var instance = api2ExecParameters(JSON.clone($model.value));

if (!jv.dataEquals($model.value, instance)) {
  $emit("update:modelValue", instance);
}


const model_change = function () {
  $data.postBodyIsText = !$data.postBodyIsText;

  if ($data.postBodyIsText) {
    var instance = api2ExecParameters(JSON.clone($model.value));
    if (!jv.dataEquals($model.value, instance)) {
      $emit("update:modelValue", instance);
    }
  } else {
    //把 postBody 的数据，设置到 api 上
    var json = JSON.parse($model.value.postBody);
    var def = getDefineValue(json);
    jv.patchJson($model.value.apiDefine.requestBodyParameters.items, def,(targetList, item)=>{
      return targetList.findIndex(it=>it.key == item.key);
    });
  }
}

defineExpose({
  getPostBody
});

</script>